package messagePacket;

import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.Map.Entry;

import Util.Util;
import io.netty.channel.Channel;
import server.ChattingServeHandler;

public class MessagePacket extends Packet {

    private String sendUser;
    private String receiveUser;
    private String message;
    private int messagetype;
    
	@Override
	public void decode(byte[] buffer) throws UnsupportedEncodingException {
		int start_pos = 4;
    	
    	int length = Util.bytes2int(buffer, start_pos);
    	start_pos += 4;
        this.sendUser = new String(buffer, start_pos, length, "UTF-8");
        start_pos += length;


        length = Util.bytes2int(buffer, start_pos);

    	start_pos += 4;
        this.receiveUser = new String(buffer, start_pos, length, "UTF-8");
        start_pos += length;

     
        length = Util.bytes2int(buffer, start_pos);

    	start_pos += 4;
        this.message = new String(buffer, start_pos, length, "UTF-8");
        start_pos += length;

        
        this.messagetype = Util.bytes2int(buffer, start_pos);
        System.out.println();
	}

	@Override
	public byte[] encode() throws UnsupportedEncodingException {
		int sendUserLength = this.sendUser.getBytes("UTF-8").length;
        int receiveUserLength = this.receiveUser.getBytes("UTF-8").length;
        int messageLength = this.message.getBytes("UTF-8").length;
        int totalLength = 4 + 4 + sendUserLength + 4 + receiveUserLength + 4 + messageLength + 4;
        byte[] buffer = new byte[totalLength];
        int offset = 0;

        // add packet type to buffer
        System.arraycopy(Util.int2bytes(Util.PACKET_MESSAGE), 0, buffer, offset, 4);
        offset += 4;
        
       
        System.arraycopy(Util.int2bytes(sendUserLength), 0, buffer, offset, 4);
        offset += 4;
        // copy send user to buffer
        System.arraycopy(sendUser.getBytes("UTF-8"), 0, buffer, offset, sendUserLength);
        offset += sendUserLength;

        System.arraycopy(Util.int2bytes(receiveUserLength), 0, buffer, offset, 4);
        offset += 4;

        System.arraycopy(receiveUser.getBytes("UTF-8"), 0, buffer, offset, receiveUserLength );
        offset += receiveUserLength;

        System.arraycopy(Util.int2bytes(messageLength), 0, buffer, offset, 4);
        offset += 4;

        System.arraycopy(message.getBytes("UTF-8"), 0, buffer, offset, messageLength);
        offset += messageLength;
        // copy sign to buffer

        byte[] messageTypeBuffer = Util.int2bytes(messagetype);
        System.arraycopy(messageTypeBuffer, 0, buffer, offset, 4);

        return buffer;
	}
	public MessagePacket() {}
	
	public MessagePacket(String sendUser, String receiveUser, String message, int messagetype) {
		super();
		this.sendUser = sendUser;
		this.receiveUser = receiveUser;
		this.message = message;
		this.messagetype = messagetype;
	}

	public String getSendUser() {
		return sendUser;
	}

	public void setSendUser(String sendUser) {
		this.sendUser = sendUser;
	}

	public String getReceiveUser() {
		return receiveUser;
	}

	public void setReceiveUser(String receiveUser) {
		this.receiveUser = receiveUser;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public int getMessagetype() {
		return messagetype;
	}

	public void setMessagetype(int messagetype) {
		this.messagetype = messagetype;
	}
	
	public void process(Channel channel, Packet packet) {
		MessagePacket messagePacket = (MessagePacket) packet;
		System.out.println("messagePacket's messageType:" +messagetype);
		if (messagetype == 1) {  
			initialAuthentication(channel, messagePacket);
		} else {
			chat(channel, messagePacket);
		}
		System.out.println("process finish!!");
	}
	/**
	 * @param newchannel
	 * @param cmsg
	 */
	private void initialAuthentication(Channel newchannel, MessagePacket cmsg) {
		if(searchUserExit(cmsg.getSendUser())) {
			ChattingServeHandler.uc.addOnlineUser(cmsg.getSendUser(),newchannel); 
		    System.out.println("On-line user-->" + ChattingServeHandler.uc.getOnlineUsers());
		   
		    MessagePacket cmwarning = new MessagePacket("服务器", cmsg.getSendUser(),"欢迎你"+cmsg.getSendUser() ,2);
		    newchannel.writeAndFlush(cmwarning); 
		    
		    
		    if (ChattingServeHandler.msgQueue.getChatMessage(cmsg.getSendUser()) != null) {
		    	newchannel.writeAndFlush(ChattingServeHandler.msgQueue.getChatMessage(cmsg.getSendUser()));
		    	ChattingServeHandler.msgQueue.removeMsgQueue(cmsg.getSendUser());
		    	for (Entry<String, Packet> entry : ChattingServeHandler.msgQueue.getMsgQueue().entrySet()) {
					System.out.println("用户"+ "key="+entry.getKey()+", Value=" + entry.getValue());
				}
		    }
		    for (Map.Entry<String, Channel> entry : ChattingServeHandler.uc.getOnlineUsers().entrySet()) {
		        if(entry.getValue() != newchannel) {
		        	MessagePacket chatMessage = new MessagePacket("服务器", "", "欢迎新客服端"+cmsg.getSendUser(), 2);
		        	entry.getValue().writeAndFlush(chatMessage);
		        }
		        
		    }
		}else {
			MessagePacket cmwarning = new MessagePacket("服务器", cmsg.getSendUser(),"已存在"+cmsg.getSendUser() ,2);
		    
		     newchannel.writeAndFlush(cmwarning); 
		}
	}
	/**
	 * @param newchannel
	 * @param cmsg
	 */
	private void chat(Channel newchannel, MessagePacket cmsg) {
		if(cmsg.getReceiveUser().equals("")){
		    for(Channel ch:ChattingServeHandler.channels) {
		        ch.writeAndFlush(cmsg);
		    }
		}else{
			try {
		        addMessage(newchannel, cmsg);
			} catch (Exception e) { 
				ChattingServeHandler.msgQueue.addMsg(cmsg.getReceiveUser(), cmsg);
				MessagePacket cmwarning = new MessagePacket("服务器", cmsg.getSendUser(),"该用户不在线" ,2);
		        newchannel.writeAndFlush(cmwarning);
			}
		}
	}
	private boolean searchUserExit(String username) {
		for (Map.Entry<String, Channel> user : ChattingServeHandler.uc.getOnlineUsers().entrySet()) {
			if(user.getKey().equals(username)) {
				return false;
			}
		}
		return true;
	}
	/**
	 *
	 * @param newchannel
	 * @param cmsg
	 */
	private void addMessage(Channel newchannel, MessagePacket cmsg) {
		if(ChattingServeHandler.uc.getChannel(cmsg.getReceiveUser())==null){ // ��������û��в����ڸ��û�������ͻ��˻ظ�������
			 MessagePacket cmwarning = new MessagePacket("服务器", cmsg.getSendUser(),"该用户不在线" ,2);
		     newchannel.writeAndFlush(cmwarning);
		     ChattingServeHandler.msgQueue.addMsg(cmsg.getReceiveUser(), cmsg);
		 }else{
			 ChattingServeHandler.uc.getChannel(cmsg.getReceiveUser()).writeAndFlush(cmsg);
		 }
	}
}
